package com.example.wang.openGLes;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.GL_COMPILE_STATUS;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
import static android.opengl.GLES20.GL_LINES;
import static android.opengl.GLES20.GL_POINTS;
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
import static android.opengl.GLES20.GL_VERTEX_SHADER;
import static android.opengl.GLES20.glAttachShader;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glCompileShader;
import static android.opengl.GLES20.glCreateProgram;
import static android.opengl.GLES20.glCreateShader;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetActiveUniform;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetShaderiv;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glLinkProgram;
import static android.opengl.GLES20.glShaderSource;
import static android.opengl.GLES20.glUniform4f;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.orthoM;
import static com.example.wang.openGLes.Constants.BYTES_PER_FLOAT;

/**
 * Created by wang on 2019/1/25.
 */

public class CusRenderer implements GLSurfaceView.Renderer {
    private FloatBuffer mVertexBuffer;
    private float[] mProjectionMatrix = new float[16];

    private int uMatrixLocation;
    private int aPositionLocation;
    private int uColorLocation;
    private Context context;
    private  static  final  int POSITION_CONPENNET_COUNT=4;

    public CusRenderer(Context context) {
        this.context = context;

        /*
		float[] tableVertices = {
			0f,  0f,
			0f, 14f,
			9f, 14f,
			9f,  0f
		};
         */
		float[] mVertexArray = {
			// Triangle Fan
			0f,  0f,
			-0.5f,-0.8f,
			0.5f, -0.8f,
			0.5f,  0.8f,
			-0.5f, 0.8f,
			-0.5f, -0.8f,
			// Next block for formatting purposes
			 // Comma here for formatting purposes

			// Line 1
			-0.5f,  0f,
			0.5f,  0f,

			// Mallets
			0f,  -0.25f,
			0f, 0.25f
                // Triangle 3
                /*-0.15f,-0.15f,0f,1f,
                0.15f,0.15f,0f,1f,
                -0.15f,0.15f,0f,1f,
                //Triangle 4
                -0.15f,-0.15f,0f,1f,
                0.15f,-0.15f,0f,1f,
                0.15f,0.15f,0f,1f,*/
		};
        /*float[] mVertexArray = new float[] { // OpenGL的坐标是[-1, 1]，这里的Vertex正好定义了一个居中的正方形
                // triangle fan x, y
                0,     0f,
                0.5f, 0.5f,
                0.5f, -0.5f,
                //triangle 2
                0.5f,  0.5f,
                -0.5f,  0.5f,
                -0.5f, -0.5f
        };*/
        mVertexBuffer = ByteBuffer.allocateDirect(mVertexArray.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(mVertexArray);
    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        // 初始化顶点数据
        //读入定点着色器
        String vertexShaderStr = TextureUtils.readShaderCodeFromResource(context, R.raw.color_vertex_shader);
        //读入片段着色器
        String fragmentShaderStr = TextureUtils.readShaderCodeFromResource(context, R.raw.color_fragment_shader);
        // 创建Shader
        final int vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
        final int fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
        //上传着色器代码
        glShaderSource(vertexShaderId, vertexShaderStr);
        glShaderSource(fragmentShaderId, fragmentShaderStr);
        //编译着色器代码
        glCompileShader(vertexShaderId);
        glCompileShader(fragmentShaderId);
        //检查编译是否成功
        final int[] compileStatus = new int[1];
        glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS,
                compileStatus, 0);
        // 创建Program
        final int programId = glCreateProgram();
        glAttachShader(programId, vertexShaderId);
        glAttachShader(programId, fragmentShaderId);
        glLinkProgram(programId);
        // 启用这个Program
        glUseProgram(programId);
        // 找到需要赋值的变量
        uMatrixLocation = glGetUniformLocation(programId, "u_Matrix");
        aPositionLocation = glGetAttribLocation(programId, "a_Position");
        uColorLocation = glGetUniformLocation(programId, "u_Color");
        // 填充数据
        mVertexBuffer.position(0);
        glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, false, 0, mVertexBuffer);
        glEnableVertexAttribArray(aPositionLocation);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        glViewport(0, 0, width, height);
        // 正交变换，只考虑竖屏的情况
        final float aspectRatio = width > height ?
                (float)width / (float) height : (float) height/ (float) width;
        if (width > height){
            //横屏
            orthoM(mProjectionMatrix , 0 , -aspectRatio , aspectRatio , -1 , 1 , -1 , 1);
        }else {
            //竖屏
            orthoM(mProjectionMatrix , 0 , -1 , 1 , -aspectRatio , aspectRatio , -1 , 1);

        }
        glUniformMatrix4fv(uMatrixLocation, 1, false, mProjectionMatrix, 0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        glClear(GL_COLOR_BUFFER_BIT);
        glUniform4f(uColorLocation, 1, 1.0f, 1.0f, 1);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
        glUniform4f(uColorLocation, 1, 0, 0, 1);
        glDrawArrays(GL_LINES,6,2);
        glUniform4f(uColorLocation, 1, 0, 0, 1);
        glDrawArrays(GL_POINTS,8,1);
        glUniform4f(uColorLocation, 1, 0, 0, 1);
        glDrawArrays(GL_POINTS,9,1);
        /*glUniform4f(uColorLocation, 0.5f, 0.5f, 1.0f, 1);
        glDrawArrays(GL_TRIANGLE_FAN, 10, 6);*/

    }
}

